﻿using NFine.Code;
using NFine.Data;
using NFine.Domain.Entity.BusinessManage;
using NFine.Domain.Entity.SystemManage;
using NFine.Domain.IRepository.BusinessManage;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace NFine.Repository.BusinessManage
{
    public class D_AmountChangeRepository : RepositoryBase<D_AmountChangeEntity>, ID_AmountChangeRepository
    {
        public D_AmountChangeEntity FindMemberEntity(string keyValue,string userId)
        {
            using (var db = new RepositoryBase())
            {
                D_AmountChangeEntity entity = new D_AmountChangeEntity();
                if (keyValue == "")
                {
                    var Record = from m in db.DbSet<D_SalaryEntity>() 
                                 where m.ID == userId
                                 select new { m.Amount };

                    foreach (var item in Record)
                    {
                        entity.F_Amount = item.Amount;
                    }
                }
                else {
                    var Record = from t in db.DbSet<D_AmountChangeEntity>()
                                 join m in db.DbSet<D_SalaryEntity>() on t.F_AccountId equals m.ID
                                 where t.F_Id == keyValue
                                 select new
                                 {
                                     t.F_Id,
                                     t.F_No,
                                     t.F_ActionType,
                                     t.F_ActionName,
                                     t.F_AccountId,
                                     t.F_UserId,
                                     t.F_Money,
                                     t.F_State,
                                     m.Amount
                                 };

                    foreach (var item in Record)
                    {
                        entity.F_Amount = item.Amount;
                        entity.F_Id = item.F_Id;
                        entity.F_No = item.F_No;
                        entity.F_ActionType = item.F_ActionType;
                        entity.F_ActionName = item.F_ActionName;
                        entity.F_AccountId = item.F_AccountId;
                        entity.F_UserId = item.F_UserId;
                        entity.F_Money = item.F_Money;
                        entity.F_State = item.F_State;
                    }
                }
                
                return entity;
            }
        }

        /// <summary>
        /// 系统初始化提现
        /// </summary>
        public void ClearInitAmount()
        {
            var _context = new RepositoryBase().Dbcontext;
            var lst = (from u in _context.Set<UserEntity>()
                       join s in _context.Set<D_SalaryEntity>() on u.F_Id equals s.ID
                       where s.Amount > 0
                       select new { u, s }).ToList();
            foreach (var item in lst)
            {
                D_AmountChangeEntity entity = new D_AmountChangeEntity();
                entity.Create();
                entity.F_Money = item.s.Amount;
                SubmitForm(entity, item.u, "");
            }
            var keys = (from sce in _context.Set<D_AmountChangeEntity>()
                        where sce.F_State == 0
                        select sce.F_Id).ToList();

            foreach (var key in keys)
            {
                UpdateForm(null, key);
            }


        }


        public void SubmitForm(D_AmountChangeEntity entity, UserEntity LoginUser, string keyValue)
        {
            using (var db = new RepositoryBase())
            {
                //var LoginInfo = OperatorProvider.Provider.GetCurrent();
                D_SalaryEntity sEntity = db.FindEntity<D_SalaryEntity>(LoginUser.F_Id);
                if (sEntity.Amount < entity.F_Money)
                    throw new Exception("用户余额不足！");
                if (keyValue == "")
                {
                    entity.F_No = "HYTX" + LoginUser.F_Account + DateTime.Now.ToString("yyyyMMddHHmmss");
                    entity.F_ActionType = 1;
                    entity.F_ActionName = SalaryChangeType.TypeValues.用户提现;
                    entity.F_AccountId = LoginUser.F_Id;
                    entity.F_AccountName = LoginUser.F_RealName;
                    entity.F_State = 0;
                    db.Insert(entity);
                }
                else
                {
                    D_AmountChangeEntity oentity = db.FindEntity<D_AmountChangeEntity>(keyValue);
                    if (oentity.F_State == 1)
                        throw new Exception("该单据已审核过，无法进行修改");
                    oentity.F_Money = entity.F_Money;
                    db.Update(oentity);
                }
            }
        }

        public void UpdateForm(D_AmountChangeEntity entity, string keyValue)
        {
            using (var db = new RepositoryBase().BeginTrans())
            {
                var LoginInfo = OperatorProvider.Provider.GetCurrent();
                D_AmountChangeEntity oentity = db.FindEntity<D_AmountChangeEntity>(keyValue);
                if (oentity.F_State == 1)
                    throw new Exception("该单据已审核过，无法重复审核");
                D_SalaryEntity saleEntity = db.FindEntity<D_SalaryEntity>(oentity.F_AccountId);
                if(saleEntity.Amount<oentity.F_Money)
                    throw new Exception("用户金额不足！");
                saleEntity.Amount = saleEntity.Amount - oentity.F_Money;
                oentity.F_State = 1;
                decimal Money = decimal.Round(oentity.F_Money * 0.05M,4);
                decimal OutMoney = oentity.F_Money-Money;
                Trigger trigger = new Trigger()
                {
                    Time = oentity.F_CreatorTime.Value,
                    UserID = oentity.F_UserId
                };
                var Outhistory = new D_SalaryHistoryEntity(Common.GuId(), oentity.F_UserId, SalaryChangeType.TypeValues.用户提现, -OutMoney, trigger, D_SalaryAccountType.Amount);
                var history = new D_SalaryHistoryEntity(Common.GuId(), oentity.F_UserId, SalaryChangeType.TypeValues.提现手续费, -Money, trigger, D_SalaryAccountType.Amount);
                var account = new D_AccountEntity(Common.GuId(), oentity.F_UserId, SalaryChangeType.TypeValues.提现手续费, Money, trigger, D_SalaryAccountType.Amount, history.ID, true);

                db.Insert(Outhistory);
                db.Insert(history);
                db.Insert(account);
                db.Update(oentity);
                db.Update(saleEntity);
                db.Commit();
            }
        }

        public void SubTransfer(D_AmountChangeEntity entity)
        {
            using (var db = new RepositoryBase().BeginTrans())
            {
                ///赵卫东增加获取测试
                var login = OperatorProvider.Provider.GetCurrent();   
                var expression = ExtLinq.True<UserEntity>();
                expression = expression.And(t => t.F_Account == entity.F_UserId);
                expression = expression.And(t => t.F_IsAdministrator == false);
                expression = expression.And(t => t.F_EnabledMark == true);
                UserEntity uentity = db.FindEntity<UserEntity>(expression);
                if (uentity == null)
                    throw new Exception("账户不存在!");
                entity.F_State = 1;
                entity.F_ActionType = 0;
                entity.F_ActionName = SalaryChangeType.TypeValues.用户转账;
                entity.F_AccountId = login.UserId;
                entity.F_AccountName = login.UserName;
                entity.F_UserName = uentity.F_AccountName;
                entity.F_UserId = uentity.F_Id;
                entity.F_No= "HYZZ" + login.UserCode + DateTime.Now.ToString("yyyyMMddHHmmss");
                D_SalaryEntity saleEntity = db.FindEntity<D_SalaryEntity>(login.UserId);
                D_SalaryEntity saleEntity1= db.FindEntity<D_SalaryEntity>(entity.F_UserId);
                if (saleEntity.Amount < entity.F_Money)
                    throw new Exception("账户余额不足！");
                saleEntity.Amount = saleEntity.Amount - entity.F_Money;
                saleEntity1.Amount= saleEntity1.Amount + entity.F_Money;
                
                decimal Money= decimal.Round(entity.F_Money, 2);
                Trigger trigger = new Trigger()
                {
                    Time = entity.F_CreatorTime.Value,
                    UserID = entity.F_AccountId
                };
                var history = new D_SalaryHistoryEntity(Common.GuId(), entity.F_AccountId, SalaryChangeType.TypeValues.用户转账, -Money, trigger, D_SalaryAccountType.Amount);
                var history1 = new D_SalaryHistoryEntity(Common.GuId(), entity.F_UserId, SalaryChangeType.TypeValues.用户转账, Money, trigger, D_SalaryAccountType.Amount);
                db.Insert(entity);
                db.Update(saleEntity);
                db.Update(saleEntity1);
                db.Insert(history);
                db.Insert(history1);
                db.Commit();
            }
        }

        public List<D_AmountChangeEntity> FindOwnTransList(Expression<Func<D_AmountChangeEntity, bool>> predicate, Expression<Func<UserEntity, bool>> predicate1, Pagination pagination)
        {
            using (var db = new RepositoryBase())
            {
                var baselinq = from sh in db.DbSet<D_AmountChangeEntity>().Where(predicate)
                               join u1 in db.DbSet<UserEntity>().Where(predicate1) on sh.F_UserId equals u1.F_Id
                               orderby sh.F_CreatorTime descending
                               select new { sh, u1 };
                //baselinq.
                //var basel = baselinq.Provider.CreateQuery(predicate);
                pagination.records = baselinq.Count();

                var query = baselinq.Skip(pagination.rows * (pagination.page - 1)).Take(pagination.rows).AsQueryable();

                List<D_AmountChangeEntity> lst = new List<D_AmountChangeEntity>();
                foreach (var obj in query)
                {
                    obj.sh.F_UserName = obj.u1.F_RealName;
                    obj.sh.F_UserNo = obj.u1.F_Account;
                    lst.Add(obj.sh);
                }
                return lst;
            }
        }
    }
}
